package com.diy.sigmund.diyuser.service.oauth2;

import com.diy.sigmund.diycommon.entity.constant.HeaderConstant;
import com.diy.sigmund.diycommon.spring.config.util.RestTemplateUtil;
import com.diy.sigmund.diycommon.util.encrypt.EncryptUtil;
import com.diy.sigmund.diyuser.common.spring.config.oauth2.OAuth2ClientConfig;
import com.diy.sigmund.diyuser.common.spring.config.oauth2.OAuth2UrlConfig;
import com.diy.sigmund.diyuser.entity.vo.CustomOAuth2AccessToken;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;

/**
 * @author ylm-sigmund
 * @since 2021/8/25 16:15
 */
@Service
public class OAuth2Service {

    private static final Logger log = LoggerFactory.getLogger(OAuth2Service.class);

    @Autowired
    private OAuth2UrlConfig oAuth2UrlConfig;
    @Autowired
    private OAuth2ClientConfig oAuth2ClientConfig;
    @Autowired
    private RestTemplateUtil restTemplateUtil;

    /**
     * token认证，调用oauth2的接口
     *
     * @param username 用户名
     * @param password 密码
     * @return CustomOAuth2AccessToken
     */
    public CustomOAuth2AccessToken tokenPassword(String username, String password) {
        // 请求头信息
        HttpHeaders headers = buildHeaderValueAuthorization();
        // 组装请求信息
        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(null, headers);

        String baseUrl = oAuth2UrlConfig.getAccessTokenUri() + OAuth2UrlConfig.PASSWORD_TYPE;
        String loginUrl = String.format(baseUrl, username, password);
        log.info("baseUrl={}", baseUrl);
        return restTemplateUtil.postForObject(loginUrl, httpEntity, CustomOAuth2AccessToken.class);
    }

    /**
     * Authorization 要加在请求头中，格式为 Basic 空格 base64(clientId:clientSecret)，
     * 这个微服务客户端的 client-id 是 user-client，client-secret 是 user-secret-8888，将这两个值通过冒号连接，
     * 并使用 base64 编码(user-client:user-secret-8888)之后的值为 dXNlci1jbGllbnQ6dXNlci1zZWNyZXQtODg4OA==，
     * 可以通过 https://www.sojson.com/base64.html 在线编码获取。
     *
     * @return String
     */
    private String getHeaderValueAuthorization() {
        String baseStr = oAuth2ClientConfig.getClientId() + ":" + oAuth2ClientConfig.getClientSecret();
        return HeaderConstant.HEADER_VALUE_BASIC + EncryptUtil.Base64Encode(baseStr);
    }

    /**
     * token刷新
     *
     * @param refreshToken refreshToken
     * @return CustomOAuth2AccessToken
     */
    public CustomOAuth2AccessToken tokenRefresh(String refreshToken) {
        // 请求头信息
        HttpHeaders headers = buildHeaderValueAuthorization();
        // 组装请求信息
        HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<>(null, headers);

        String baseUrl = oAuth2UrlConfig.getAccessTokenUri() + OAuth2UrlConfig.REFRESH_TOKEN_TYPE;
        String loginUrl = String.format(baseUrl, refreshToken);
        log.info("baseUrl={}", baseUrl);
        return restTemplateUtil.postForObject(loginUrl, httpEntity, CustomOAuth2AccessToken.class);
    }

    private HttpHeaders buildHeaderValueAuthorization() {
        HttpHeaders headers = new HttpHeaders();
        final String headerValueAuthorization = getHeaderValueAuthorization();
        log.info("headerValueAuthorization={}", headerValueAuthorization);
        headers.add(HeaderConstant.AUTHORIZATION, headerValueAuthorization);
        return headers;
    }
}
